﻿using System;
using System.Reflection;
using Comm.PublicClass;
using WsProtocol.IEC62056;

namespace WsProtocol.IEC62056MDL
{
    public class TMeter62056
    {
        private string m_MeterNO;
        private string m_DedicatedKey;
        private string m_EncryptedKey;
        private string m_BroadcastEKey;
        private string m_AuthenKey;
        private string m_FactoryCode;
        private UInt32 m_IC; //帧计数器
        private string m_MasterKey;

        private int iContextName = 0;
        
        public int securitymodeexpand = 0; 

        public int SendCount { get; set; }  //发送计数
        //public int NewSendCount { get; set; }  //新的发送计数器
        public int RecCount { get; set; }  //接收计数       

        public string MeterNO 
        {
            get { return m_MeterNO; }
            set
            {
                m_MeterNO = value;
                EncParams.MeterNo = value;
            }
        }  //表号        
        public int MeterCommAddr{get;set;}//地址        
        public string PassWord { get; set; }  //密码
        public string AppProVersion { get; set; }  //应用层协议版本号       
        public string ProConform { get; set; }  //协议一致性块        
        public string SendMaxSize { get; set; }  //发送最大信息域长度
        public string RecMaxSize { get; set; }  //接收最大信息域长度 
        public string SendMaxWindow { get; set; }  //发送窗口大小
        public string RecMaxWindow { get; set; }  //接收窗口大小
        public string APDUSize { get; set; }  //最大可处理APDU尺寸
        public int AddrLen { get; set; }  //地址长度

        public string udpCAddr { get; set; }  //UDP客户端地址
        public string udpSAddr { get; set; }  //UDP服务端地址

        public TMeterTypeRole MTRole; //hxh 关联的角色对象    

        public string SecurityPassWord   //用于传给底层的密码
        {
            get
            {
                string apass = PassWord;
                string[] passlst = apass.Split(',');
                try
                {
                    switch (SecurityModeExpand)
                    {
                        case AuthenticationExpand.LLS1:
                            if (passlst.Length > 0)
                                apass = passlst[0];
                            break;
                        case AuthenticationExpand.LLS2:
                            if (passlst.Length > 1)
                                apass = passlst[1];
                            else
                                apass = string.Empty;
                            break;
                        case AuthenticationExpand.LLS3:
                            if (passlst.Length > 2)
                                apass = passlst[2];
                            else
                                apass = string.Empty;
                            break;
                    }
                }
                catch
                {
                }
                return apass;
            }
            set { }
        }
        //扩展安全验证等级
        public AuthenticationExpand SecurityModeExpand
        {
            get
            {
                try
                {
                    return (AuthenticationExpand)securitymodeexpand;
                }
                catch
                {
                    return AuthenticationExpand.NoAuth;
                }
            }
            set { securitymodeexpand = (int)value;
                try
                {
                    switch (value)
                    {
                        //case AuthenticationExpand.HLS:
                        //    EncParams.apduAuth = Authentication.HLS;
                        //    break;
                        //case AuthenticationExpand.LLS:
                        case AuthenticationExpand.LLS1:
                        case AuthenticationExpand.LLS2:
                        case AuthenticationExpand.LLS3:
                            EncParams.apduAuth = Authentication.LLS;
                            break;
                        case AuthenticationExpand.NoAuth:
                            EncParams.apduAuth = Authentication.NoAuth;
                            break;
                        case AuthenticationExpand.HLS_GMAC:
                            EncParams.apduAuth = Authentication.HLS_GMAC;
                            break;
                        //case AuthenticationExpand.HLS_ECDSA:
                        //    EncParams.apduAuth = Authentication.HLS_ECDSA;
                        //    break;
                        //case AuthenticationExpand.HLS_MD5:
                        //    EncParams.apduAuth = Authentication.HLS_MD5;
                        //    break;
                        //case AuthenticationExpand.HLS_SHA_1:
                        //    EncParams.apduAuth = Authentication.HLS_SHA_1;
                        //    break;
                        //case AuthenticationExpand.HLS_SHA_256:
                        //    EncParams.apduAuth = Authentication.HLS_SHA_256;
                        //    break;
                    }                    
                }
                catch
                {
                }
            }

        }

        #region //加密所需要的参数，还有MeterNo，同时传入EncParams对象相关属性
        //安全验证等级 用于传给底层
        public Authentication SecurityMode
        {
            get
            {
                Authentication authen = Authentication.NoAuth;
                try
                {
                    switch (SecurityModeExpand)
                    {
                        //case AuthenticationExpand.HLS:
                        //    authen = Authentication.HLS;
                        //    break;
                        //case AuthenticationExpand.LLS:
                        case AuthenticationExpand.LLS1:
                        case AuthenticationExpand.LLS2:
                        case AuthenticationExpand.LLS3:
                            authen = Authentication.LLS;
                            break;
                        case AuthenticationExpand.NoAuth:
                            authen = Authentication.NoAuth;
                            break;
                        case AuthenticationExpand.HLS_GMAC:
                            authen = Authentication.HLS_GMAC;
                            break;
                        //case AuthenticationExpand.HLS_ECDSA:
                        //    authen = Authentication.HLS_ECDSA;
                        //    break;
                        //case AuthenticationExpand.HLS_MD5:
                        //    authen = Authentication.HLS_MD5;
                        //    break;
                        //case AuthenticationExpand.HLS_SHA_1:
                        //    authen = Authentication.HLS_SHA_1;
                        //    break;
                        //case AuthenticationExpand.HLS_SHA_256:
                        //    authen = Authentication.HLS_SHA_256;
                        //    break;
                    }                    
                }
                catch
                {
                }
                return authen;
            }
            set { }// EncParams.apduAuth = value; }
        }

        public RequirContext ContextName
        {
            get { return (RequirContext)iContextName; }
            set
            {
                try
                {
                    iContextName = (int)value;
                    EncParams.ContextName = value;
                }
                catch (Exception ex)
                {
                    EncParams.ContextName = RequirContext.LN_NoCipher;
                }
            }
        }
        public string DedicatedKey
        {
            get { return m_DedicatedKey; }
            set
            {
                m_DedicatedKey = value;
                EncParams.Key.DK = value;
            }
        }
        public string EncryptedKey
        {
            get { return m_EncryptedKey; }
            set
            {
                m_EncryptedKey = value;
                EncParams.Key.EK = value;
            }
        }
        public string BroadcastEKey
        {
            get { return m_BroadcastEKey; }
            set
            {
                m_BroadcastEKey = value;
                EncParams.Key.BK = value;
            }
        }
        public string AuthenKey
        {
            get { return m_AuthenKey; }
            set
            {
                m_AuthenKey = value;
                EncParams.Key.AK = value;
            }
        }
        public string FactoryCode
        {
            get { return m_FactoryCode; }
            set
            {
                m_FactoryCode = value;
                EncParams.FactoryCode = value;
            }
        }
        public UInt32 IC  //帧计数器
        {
            get { return m_IC; }
            set
            {
                m_IC = value;
                EncParams.IC = value;
            }
        }

        public string MasterKey {

            get { return m_MasterKey; }
            set
            {
                m_MasterKey = value;
                EncParams.Key.MK = value;
            }
        }

        public Encryption EncParams; //加密对象 hxh
        #endregion

        public TMeter62056()
        {
            MTRole = new TMeterTypeRole();
            EncParams = new Encryption();

            MeterNO = string.Empty;
            MeterCommAddr = 1;
            PassWord = string.Empty;
            AppProVersion = "6";
            //SoftEdition = string.Empty;
            //HardwareEdition = string.Empty;
            //SoftEditionDate = string.Empty;
            //HardEdionDate = string.Empty;
            //FactoryExpand = string.Empty;

            //Identity = false;
            ProConform = "007E1F";  //协议一致性块
            //FuncConform = "FF";
            SendMaxSize = "1024"; //发送最大信息域长度
            RecMaxSize = "1024"; //接收最大信息域长度 
            SendMaxWindow = "1";  //发送窗口大小
            RecMaxWindow = "1";  //接收窗口大小
            AddrLen = 4;
            ContextName = RequirContext.LN_Cipher;
            APDUSize = PtlConsts.defApduSize.ToString();

            MasterKey = "00112233445566778899AABBCCDDEEFF";
            EncryptedKey = "000102030405060708090A0B0C0D0E0F";
            BroadcastEKey = "00112233445566778899AABBCCDDEEFF";
            AuthenKey = "D0D1D2D3D4D5D6D7D8D9DADBDCDDDEDF";
            DedicatedKey = string.Empty;// "00112233445566778899AABBCCDDEEFF";

            FactoryCode = "WSE";
            IC = 0;

            udpCAddr = string.Empty;
            udpSAddr = string.Empty;
            
            Reset();
        }

        //复制自身
        public TMeter62056 Copy()
        {
            //新建一个
            TMeter62056 newmeter = new TMeter62056();
            //复制属性
            PropertyInfo[] fromFields = typeof(TMeter62056).GetProperties();
            PubFunction.SetProperties(fromFields, this, newmeter);

            newmeter.EncParams = this.EncParams.Copy();
            //newmeter.MTRole = this.MTRole.Copy(true);
            return newmeter;
        }

        ///// <summary>
        ///// 获取新的发送计数
        ///// </summary>
        ///// <returns></returns>
        //public int GetNewSendCount()
        //{
        //    NewSendCount = SendCount + 1;
        //    if (NewSendCount > 7)
        //        NewSendCount = 0;
        //    return NewSendCount;
        //}

        ///// <summary>
        ///// 新的发送计数器得到确认
        ///// </summary>
        //public void ConfirmSendCount()
        //{
        //    SendCount = NewSendCount;
        //}

        public void Reset()
        {
            SendCount = 0;
            RecCount = 0;
            
           
            ResetCount();
        }

        public void ResetCount()
        {
            SendCount = -1;
            //NewSendCount = SendCount;
            RecCount = 0;
        }
    }

}
